/**
 * 
 * Copyright (C) 2011 Cody Stoutenburg . All rights reserved.
 *
 *       This program is free software; you can redistribute it and/or
 *       modify it under the terms of the GNU Lesser General Public License
 *       as published by the Free Software Foundation; either version 2.1
 *       of the License, or (at your option) any later version.
 *
 *       This program is distributed in the hope that it will be useful,
 *       but WITHOUT ANY WARRANTY; without even the implied warranty of
 *       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *       GNU Lesser General Public License for more details.
 *
 *       You should have received a copy of the GNU Lesser General Public License
 *       along with this program; if not, write to the Free Software
 *       Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. 
 * 
 */
package ca.usherbrooke.behaviours.world;

import jade.lang.acl.ACLMessage;
import jade.lang.acl.MessageTemplate;
import jade.lang.acl.UnreadableException;
import ca.usherbrooke.agent.message.RequestMessageObjectController;
import ca.usherbrooke.agent.world.BasicWorldAgent;
import ca.usherbrooke.behaviours.BasicRequestReponderBehaviour;
import ca.usherbrooke.model.entity.IEntityModel;
import ca.usherbrooke.model.equipment.EquipmentModel;
import ca.usherbrooke.model.equipment.ProtectionModel;
import ca.usherbrooke.model.equipment.WeaponModel;
import ca.usherbrooke.tools.position.Vector2D;
import ca.usherbrooke.utils.ExceptionTool;

/**
 * @author Cody Stoutenburg
 * 
 */
public class BasicWorldResponder extends
		BasicRequestReponderBehaviour<BasicWorldAgent> {

	public final static String REQUEST_CONTROLLER_PROTOCOL = "proto.request.controller";

	public final static MessageTemplate REQUEST_TEMPLATE = MessageTemplate.and(
			MessageTemplate.MatchProtocol(REQUEST_CONTROLLER_PROTOCOL),
			MessageTemplate.MatchPerformative(ACLMessage.REQUEST));

	private static final long serialVersionUID = 1L;

	/**
	 * @param a
	 * @param mt
	 */
	public BasicWorldResponder(BasicWorldAgent a) {
		super(a, REQUEST_TEMPLATE, REQUEST_CONTROLLER_PROTOCOL);
	}

	protected IEntityModel getEntity(Long guid) {
		return this.getAgent().getWorld().getEntity(guid);
	}

	@Override
	protected ACLMessage prepareResult(ACLMessage request) {
		ACLMessage response = this.buildResultMessage(request);

		// if delta <= 0 then we are in pause so we need to ignore all message
		if (this.getAgent().getDelta() > 0) {
			try {
				RequestMessageObjectController<?> message = (RequestMessageObjectController<?>) request
						.getContentObject();

				Long guid = message.getGUID();
				switch (message.getRequestType()) {

				case RequestMessageObjectController.REQUEST_SET_SPEED:
					Vector2D newSpeed = (Vector2D) message.getValue();
					this.getEntity(guid).setSpeed(newSpeed);
					response.setContent("speed set");
					break;
				case RequestMessageObjectController.REQUEST_SET_TARGET_SPEED:
					Vector2D targetPosition = (Vector2D) message.getValue();
					this.getEntity(guid).setTargetPosition(targetPosition);
					response.setContent("target position set");
					break;
				case RequestMessageObjectController.REQUEST_JUMP:
					this.getEntity(guid).doJump();
					response.setContent("jump done");
					break;
				case RequestMessageObjectController.REQUEST_GRAP_OBJECT: {
					Long eqGuid = (Long) message.getValue();
					EquipmentModel equipement = this.getAgent().getWorld()
							.getEquipment(eqGuid);
					this.getEntity(guid).pickUp(equipement);
					break;
				}
				case RequestMessageObjectController.REQUEST_DROP_OBJECT: {
					Long eqGuid = (Long) message.getValue();
					EquipmentModel equipement = this.getAgent().getWorld()
							.getEquipment(eqGuid);
					this.getEntity(guid).putDown(equipement);
					break;
				}
				case RequestMessageObjectController.REQUEST_ATTACK: {
					Long entityGuid = (Long) message.getValue();
					IEntityModel entity = this.getAgent().getWorld()
							.getEntity(entityGuid);
					this.getEntity(guid).doAttack(entity);
					break;
				}
				case RequestMessageObjectController.REQUEST_PUT_DOWN_PROTECTION: {
					Long protectionGuid = (Long) message.getValue();
					ProtectionModel protection = (ProtectionModel) this
							.getAgent().getWorld().getEquipment(protectionGuid);
					this.getEntity(guid).putDownProtection(protection);
					break;
				}
				case RequestMessageObjectController.REQUEST_TAKE_PROTECTION: {
					Long protectionGuid = (Long) message.getValue();
					ProtectionModel protection = (ProtectionModel) this
							.getAgent().getWorld().getEquipment(protectionGuid);
					this.getEntity(guid).takeProtection(protection);
					break;
				}
				case RequestMessageObjectController.REQUEST_PUT_DOWN_WEAPON: {
					this.getEntity(guid).putDownWeapon();
					break;
				}
				case RequestMessageObjectController.REQUEST_TAKE_WEAPON: {
					Long protectionGuid = (Long) message.getValue();
					WeaponModel weapon = (WeaponModel) this.getAgent()
							.getWorld().getEquipment(protectionGuid);
					this.getEntity(guid).takeWeapon(weapon);
					break;
				}
				}
			} catch (UnreadableException ex) {
				ExceptionTool.showError(ex);
			}
		}

		return response;
	}
}
